<style lang="scss">
.pcomputed {

	@mixin n-row1 {
		display: flex;
		justify-content: flex-start;
		align-items: center;
	}

	&,
	*:not([class^='el-']) {
		margin: 0;
		padding: 0;
		font: inherit;
		color: inherit;
		list-style: none;
		outline: none;
		box-sizing: border-box;
	}

	width: 100%;
	height: 100%;
	overflow: hidden;
	overflow-y: auto;
	position: relative;
	padding: 20px !important;

	.pcomputed-list {
		background: #fff;

		>li {
			padding: 20px;
			border-bottom: 1px solid #eee;

			>h3 {
				color: #000;
				font-weight: bold;
				@include n-row1;
				font-size: 16px;
			}

			.pcomputed-list-des {
				@include n-row1;
				margin-top: 40px;
				font-size: 14px;
				color: #555;
				gap: 20px;
				align-items: flex-start;

				>span {
					@include n-row1;
					justify-content: flex-end;
					height: 30px;
				}

				>div {
					flex: 1;
					width: 0;

					>p {
						@include n-row1;
						gap: 10px;
						justify-content: flex-start;
						margin-bottom: 15px;

						.el-input {
							width: 200px;
						}
					}
				}
			}

			>p {
				color: #999;
				font-size: 13px;
				@include n-row1;
				margin-top: 20px;
				background: #f6f6f6;
				padding: 10px;
				gap: 10px;

				>img {
					width: 200px;
				}
			}

			>footer {
				margin-top: 20px;
				@include n-row1;

				>span {
					color: #999;
					font-size: 14px;
					flex: 1;
					width: 0;
					font-style: initial;
				}
			}
		}
	}

	.pcomputed-res {
		margin-top: 20px;
		background: #fff;
		padding: 20px;

		>h3 {
			@include n-row1;
			justify-content: center;
			font-weight: bold;
			color: #000;
			font-size: 24px;
			line-height: 50px;
		}

		>h4 {
			@include n-row1;
			justify-content: flex-start;
			font-weight: bold;
			color: #000;
			font-size: 20px;
			line-height: 50px;
			margin-top: 20px;
		}

		>ul {
			@include n-row1;
			margin-top: 10px;
			flex-wrap: wrap;
			font-size: 18px;
			align-content: flex-start;

			>li {
				height: 36px;
				border-bottom: 1px solid #eee;
				flex: 0 0 50%;
				width: 0;
				padding: 0 10px;
				@include n-row1;
			}
		}

		>footer {
			@include n-row1;
			margin-top: 20px;

			>span {
				@include n-row1;
				gap: 10px;
				flex: 1;
				width: 0;
				justify-content: flex-start;

				.el-input {
					width: 200px;
				}
			}

			>article {
				.el-button {
					margin: 0;
					margin-bottom: 10px;
					width: 120px;
					display: block;
				}
			}
		}
	}

	.pcomputed-dialog {
		>h3 {
			@include n-row1;
			justify-content: flex-end;
		}

		>ul {
			margin-top: 20px;

			>li {
				@include n-row1;
				gap: 10px;
				font-size: 14px;
				color: #555;
				border-bottom: 1px solid #eee;
				height: 40px;

				>i {
					color: #999;
				}

				.el-button {
					margin-left: auto;

					&+.el-button {
						margin-left: 0;
					}
				}
			}
		}
	}

}
</style>

<template>
	<div class="app-container pcomputed">
		<ul class="pcomputed-list">
			<li>
				<h3>基础参数计算</h3>
				<article class="pcomputed-list-des">
					<span>请输入</span>
					<div>
						<p>年输量：(×10⁸ m³)<el-input v-model="params2.a" /></p>
						<p>年工作天数：(天):<el-input v-model="params2.b" /></p>
						<p>设计压力：(MPa)<el-input v-model="params2.s" /></p>
						<p>管道直径：(m)<el-input v-model="params2.d" /></p>
						<p>钢材型号：X<el-input v-model="params2.t" /></p>
						<p>地区等级：<el-input v-model="params2.v" /></p>
					</div>
				</article>
				<footer>
					<span>
						<p>输气流量：{{ params.n }} m³/s</p><br>
						<p>管道壁厚：{{ params.e }} m</p>
					</span>
					<el-button type="primary" plain @click="computed1">计算</el-button>
					<el-button
						@click="handleClickAndClear($event, ['a', 'b', 's', 'd', 't', 'n', 'e', 'v'])">清零</el-button>
				</footer>
			</li>
			<li>
				<h3>长输输气管道水力计算</h3>
				<article class="pcomputed-list-des">
					<span>请输入</span>
					<div>
						<p>相对密度：<el-input v-model="params2.h" /></p>
						<p>动力粘度：(Pa·s)<el-input v-model="params2.l" /></p>
					</div>
				</article>
				<footer>
					<span>
						<p>雷诺数：{{ params.c }}</p><br>
						<p>水力摩阻系数：{{ params.m }}</p>
					</span>
					<el-button type="primary" plain @click="computed2">计算</el-button>
					<el-button @click="handleClickAndClear($event, ['h', 'l', 'c', 'm'])">清零</el-button>
				</footer>
			</li>
			<li>
				<h3>长输输气管道布站计算</h3>
				<article class="pcomputed-list-des">
					<span>请输入</span>
					<div>
						<p>管道总长度：(km)<el-input v-model="params2.f" /></p><br>
						<p>天然气温度：(K)<el-input v-model="params2.g" /></p><br>
						<p>压缩因子：<el-input v-model="params2.i" /></p><br>
						<p>压比：<el-input v-model="params2.u" /></p><br>
						<p>末段起点最高压力：(MPa)<el-input v-model="params2.j" /></p><br>
						<p>末段终点最低压力：(MPa)<el-input v-model="params2.k" /></p>
					</div>
				</article>
				<footer>
					<span>
						<p>末端最优长度：{{ params.o }} km</p><br>
						<p>储气能力：{{ params.p }} ×10⁵ m³</p><br>
						<p>站间距：{{ params.q }} km</p><br>
						<p>压气站数目：{{ params.r }} 座</p>
					</span>
					<el-button type="primary" plain @click="computed3">计算</el-button>
					<el-button
						@click="handleClickAndClear($event, ['f', 'g', 'i', 'j', 'k', 'o', 'p', 'q', 'r', 'u'])">清零</el-button>
				</footer>
			</li>
		</ul>

		<div class="pcomputed-res">
			<h3>结果展示</h3>
			<h4>输入值：</h4>
			<ul>
				<li>年输量：{{ params.a }} ×10⁸ m³</li>
				<li>年工作天数：{{ params.b }} 天</li>
				<li>设计压力：{{ params.s }} MPa</li>
				<li>管道总长度：{{ params.f }} km</li>
				<li>管道直径：{{ params.d }} m</li>
				<li>管道壁厚：{{ params.e }} m</li>
				<li>钢材型号：X{{ params.t }}</li>
				<li>天然气温度：{{ params.g }} K</li>
				<li>相对密度：{{ params.h }}</li>
				<li>动力粘度：{{ params.l }} Pa·s</li>
				<li>压缩因子：{{ params.i }}</li>
				<li>压比：{{ params.u }}</li>
				<li>末段起点最高压力：{{ params.j }} MPa</li>
				<li>末段终点最低压力：{{ params.k }} MPa</li>
			</ul>
			<h4>输出值：</h4>
			<ul>
				<li>输气流量：{{ params.n }} m³/s</li>
				<li>雷诺数：{{ params.c }}</li>
				<li>水力摩阻系数：{{ params.m }}</li>
				<li>末端最优长度：{{ params.o }} km</li>
				<li>储气能力：{{ params.p }} m³</li>
				<li>站间距：{{ params.q }} km</li>
				<li>压气站数目：{{ params.r }} 座</li>
			</ul>
			<footer>
				<span>项目名：<el-input v-model="params.name" /></span>
				<article>
					<el-button plain type="primary" @click="save">存储</el-button>
					<el-button plain type="primary" @click="handleClickAndShow">编辑</el-button>
				</article>
			</footer>
		</div>
		<el-dialog title="项目列表" v-model="listConf.show">
			<div class="pcomputed-dialog">
				<h3><el-button type="primary" @click="add" plain>新增项目</el-button></h3>
				<ul>
					<li v-for="item in filteredList" :key="item.id">
						<i>{{ filteredList.indexOf(item) + 1 }}</i>
						{{ item.name }}
						<el-button type="primary" @click="check(item)" link>编辑</el-button>
						<el-button type="danger" @click="del(item)" link>删除</el-button>
					</li>
				</ul>
			</div>
		</el-dialog>
	</div>
</template>
<script>
export default {
	data() {
		window.vm = this
		return {
			listConf: {
				show: true,
				list: [
					{
						id: null,
						name: '',
						a: '',   //年输量
						b: '',   //年工作天数
						c: '',   //雷诺数
						d: '',   //管道直径
						e: '',   //管道壁厚
						f: '',   //管道总长度
						g: '',   //天然气温度
						h: '',   //天然气相对密度
						i: '',   //压缩因子
						j: '',   //末段起点最高压力
						k: '',   //末段终点最低压力
						l: '',   //动力粘度
						m: '',   //摩阻系数
						n: '',   //输气流量
						o: '',   //末端最优长度
						p: '',   //储气能力
						q: '',   //站间距
						r: '',   //压气站数目
						s: '',   //设计压力
						t: '',   //钢材型号
						u: '',	 //压比
						v: '',	 //地区等级
					},
				],
			},
			params: {
				id: null,
				name: '',
				a: '',   //年输量
				b: '',   //年工作天数
				c: '',   //雷诺数
				d: '',   //管道直径
				e: '',   //管道壁厚
				f: '',   //管道总长度
				g: '',   //天然气温度
				h: '',   //天然气相对密度
				i: '',   //压缩因子
				j: '',   //末段起点最高压力
				k: '',   //末段终点最低压力
				l: '',   //动力粘度
				m: '',   //摩阻系数
				n: '',   //输气流量
				o: '',   //末端最优长度
				p: '',   //储气能力
				q: '',   //站间距
				r: '',   //压气站数目
				s: '',   //设计压力
				t: '',   //钢材型号
				u: '',	 //压比
				v: '',	 //地区等级
			},

			params2: {
				a: '',
				b: '',
				s: '',
				d: '',
				t: '',
				h: '',
				l: '',
				f: '',
				g: '',
				j: '',
				k: '',
				i: '',
				u: '',
				v: '',
			}
		}
	},
	created() {
		this.load();
	},
	computed: {
		filteredList() {
			const username = this.$store.state.userInfo.username;
			return this.listConf.list.filter(item => item.username === username);
		}
	},

	watch: {

	},

	beforeUnmount() {
		this.exitsave(); // 在组件销毁前调用save方法  
		location.reload();
	},
	methods: {
		show(event) {
			this.handleClick(event)
		},
		load() {
			this.$request.get("/computed", {
				params: {
					id: this.id,
					username: this.username,
					name: this.name,
					a: this.a,
					b: this.b,
					c: this.c,
					d: this.d,
					e: this.e,
					f: this.f,
					g: this.g,
					h: this.h,
					i: this.i,
					j: this.j,
					k: this.k,
					l: this.l,
					m: this.m,
					n: this.n,
					o: this.o,
					p: this.p,
					q: this.q,
					r: this.r,
					s: this.s,
					t: this.t,
					v: this.v,
				}
			}).then(res => {
				this.listConf.list = res
			})
		},
		del(item, idx) {
			if (this.params.id === item.id) this.params = this.params2 = {};
			const id = item.id
			this.$request.delete("/computed/" + id).then(res => {
				if (res) {
					this.$message.success("删除成功")
				} else {
					this.$message.error("删除失败")
				}
			})
			location.reload();
		},

		add() {
			const newData = {
				username: this.$store.state.userInfo.username,
				name: '新的项目',
				// 其他字段可以省略，或者根据需要设置为空字符串或null  
				// 在这个例子中，我们省略了其他字段，因为它们不是必需的  
			};

			this.$request.post("/computed", newData).then(res => {
				if (res) { // 假设后端响应包含一个success字段来表示操作是否成功  
					this.$message.success("保存成功");
				} else {
					this.$message.error("保存失败");
				}
			}).catch(error => {
				console.error(error); // 输出错误信息到控制台，便于调试  
				this.$message.error("保存过程中发生错误");
			});
			location.reload();
		},
		handleClickAndShow(event) {
			this.listConf.show = true;
			this.handleClick(event);
		},
		check(item) {
			this.listConf.show = false;
			this.params = JSON.parse(JSON.stringify(item))
			this.params2 = JSON.parse(JSON.stringify(item))
		},
		save(event) {
			this.handleClick(event)
			if (!this.isCheck()) return;
			const { listConf: { list }, params } = this;
			const idx = list.findIndex(v => v.id === params.id);
			if (!~idx) return;
			list.splice(idx, 1, JSON.parse(JSON.stringify(params)))
			this.params.a = this.params2.a
			this.params.b = this.params2.b
			this.params.s = this.params2.s
			this.params.d = this.params2.d
			this.params.t = this.params2.t
			this.params.h = this.params2.h
			this.params.l = this.params2.l
			this.params.g = this.params2.g
			this.params.f = this.params2.f
			this.params.j = this.params2.j
			this.params.k = this.params2.k
			this.params.i = this.params2.i
			this.params.u = this.params2.u
			this.params.v = this.params2.v
			this.$request.post("/computed", this.params).then(res => {
				if (res) {
					this.$message.success("保存成功")
				} else {
					this.$message.error("保存失败")
				}
			})
			location.reload();
		},
		exitsave() {
			if (!this.isCheck1()) return;
			const { listConf: { list }, params } = this;
			const idx = list.findIndex(v => v.id === params.id);
			if (!~idx) return;
			list.splice(idx, 1, JSON.parse(JSON.stringify(params)))
			this.params.a = this.params2.a
			this.params.a = this.params2.a
			this.params.b = this.params2.b
			this.params.s = this.params2.s
			this.params.d = this.params2.d
			this.params.t = this.params2.t
			this.params.h = this.params2.h
			this.params.l = this.params2.l
			this.params.g = this.params2.g
			this.params.f = this.params2.f
			this.params.j = this.params2.j
			this.params.k = this.params2.k
			this.params.i = this.params2.i
			this.params.u = this.params2.u
			this.params.v = this.params2.v
			this.$request.post("/computed", this.params).then(res => {
				if (res) {
					this.$message.success("保存成功")
				} else {
					this.$message.error("保存失败")
				}
			})
		},
		handleClickAndClear(event, keysToClear) {
			// 先执行 handleClick 的逻辑  

			let target = event.target;
			if (target.nodeName == "I" || target.nodeName == "SPAN") {
				target = event.target.parentNode;
			}
			target.blur();

			// 然后执行 clear 的逻辑来清空参数  
			this.clear(keysToClear);

			// 可以在这里继续添加其他操作  
		},

		clear(keys) {
			keys.forEach(k => {
				this.params[k] = '';
				this.params2[k] = '';
			});
		},

		isCheck() {
			if (!this.params.id) return (this.$message.error('请选择项目'), 0)
			return true;
		},

		isCheck1() {
			if (!this.params.id) return
			return true;
		},

		isNull(v) {
			return ['', null, undefined].includes(v);
		},
		computed1(event) {
			this.handleClick(event)
			const { params2: { a, b, s, d, t, v }, params, isNull } = this;
			if (!this.isCheck()) return;
			if (isNull(a) || isNull(b) || isNull(s) || isNull(d) || isNull(t) || isNull(v)) return this.$message.error('请完善输入')
			params.a = a;
			params.b = b;
			params.s = s;
			params.d = d;
			params.t = t;
			params.v = v;
			let gasflow = a * Math.pow(10, 8) / (b * 24 * 3600);
			params.n = gasflow.toFixed(3);
			let stress = t * 7 - 5;
			let wallthickness = s * d / 2 / stress / this.calculateZ(v);
			console.log(this.calculateZ(v))
			let values = [0.0064, 0.0071, 0.0079, 0.0084, 0.0095, 0.0108, 0.0123, 0.0143, 0.0159, 0.0174, 0.0191];
			let closestLargerValue = this.findClosestLargerValue(wallthickness, values);
			params.e = closestLargerValue.toFixed(4);
		},
		computed2(event) {
			this.handleClick(event)
			const { params2: { l }, params2: { h }, params, isNull } = this;
			if (!this.isCheck()) return;
			if (isNull(params.n) || isNull(params.e)) return this.$message.error('请完成基础参数的计算');
			if (isNull(l) || isNull(h)) return this.$message.error('请完善输入');
			params.l = l;
			params.h = h;
			let re = 1.536 * params.n * h / (params.d - 2 * params.e) / l;
			params.c = re.toFixed(0);
			let ms = 0.01;
			let ns;
			do {
				ns = ms
				ms = Math.pow((1 / ((-2) * Math.log10((0.01 / 3.7 / (params.d - 2 * params.e) / 1000 + 2.51 / re / Math.pow(ms, 0.5))))), 2)
			} while (Math.abs(ns - ms) > 0.000001);

			let frictioncoefficient = ms / 0.95 / 0.95;
			params.m = frictioncoefficient.toFixed(5);
		},
		computed3(event) {
			this.handleClick(event)
			const { params2: { f, g, j, k, i, u }, params, isNull } = this;
			if (!this.isCheck()) return;
			if (isNull(params.c) || isNull(params.m)) return this.$message.error('请完成管道水力参数的计算')
			if (isNull(f) || isNull(g) || isNull(j) || isNull(k) || isNull(i) || isNull(u)) return this.$message.error('请完善输入')
			params.f = f * 1;
			params.g = g;
			params.j = j;
			params.k = k;
			params.i = i;
			params.u = u;
			let j1 = j * 1000000;
			let k1 = k * 1000000;
			let cn = (params.m * i * g * params.h) / ((Math.pow(0.03848, 2) * Math.pow(params.d - params.e, 5)));
			let endlength = (Math.pow(j1, 2) - Math.pow(k1, 2)) / (2 * cn * (Math.pow(params.n, 2)) * 1000);
			params.o = endlength.toFixed(3);
			let p2max = Math.sqrt((Math.pow(j1, 2) - cn * endlength * 1000 * Math.pow(params.n, 2)));
			let averagepmax = (2 / 3) * (j1 + Math.pow(p2max, 2) / (j1 + p2max));
			let p1min = Math.sqrt((Math.pow(k1, 2) + cn * endlength * 1000 * Math.pow(params.n, 2)));
			let averagepmin = (2 / 3) * (p1min + Math.pow(k1, 2) / (p1min + k1));
			let gasstoragecapacity = 0.25 * 3.14 * Math.pow(params.d - params.e, 2) * (averagepmax - averagepmin) * 293.15 * endlength * 0.01 / (g * i * Math.pow(10, 5));
			params.p = gasstoragecapacity.toFixed(3);
			let letinpressure = j1 / u;
			let spacing = (Math.pow(j1, 2) - Math.pow(letinpressure, 2)) / cn / Math.pow(params.n, 2) / 1000
			params.q = spacing.toFixed(3);
			let stationnumber = (f - endlength) / spacing + 1;
			params.r = stationnumber.toFixed(0);
		},
		handleClick(event) {
			// 点击后鼠标移开恢复按钮默认样式(如果按钮没有加icon图标的话，target.nodeName == "I"可以去掉)
			let target = event.target;
			if (target.nodeName == "I" || target.nodeName == "SPAN") {
				target = event.target.parentNode;
			}
			target.blur();
			//进行其他操作
		},
		findClosestLargerValue(x, values) {
			// 过滤出比x大的值  
			let largerValues = values.filter(v => v > x);

			// 如果没有比x大的值，则返回null或其他默认值  
			if (largerValues.length === 0) {
				return x;
			}

			// 在比x大的值中找到离x最近的值  
			return largerValues.reduce((prev, curr) => {
				return (curr - x < prev - x ? curr : prev);
			}, largerValues[0]);
		},
		calculateZ(v) {
			let z;
			switch (v) {
				case "1":
					z = 0.72;
					break;
				case "2":
					z = 0.6;
					break;
				case "3":
					z = 0.5;
					break;
				case "4":
					z = 0.4;
					break;
				default:
					z = 0.72;
					break;
			}
			return z;
		},
	}

}
</script>